package com.glsc.ngateway.platform.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.common.enums.Constant;
import com.glsc.ngateway.common.api.common.enums.DictConstant;
import com.glsc.ngateway.common.api.common.enums.PlatformConstant;
import com.glsc.ngateway.common.api.common.utils.PageUtil;
import com.glsc.ngateway.common.api.flowable.dto.*;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamCopyDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamCreateDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamDoTaskDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamRollbackDto;
import com.glsc.ngateway.common.api.flowable.dto.task.config.ProcessEditConfigDto;
import com.glsc.ngateway.common.api.flowable.feign.IFeignFlowableService;
import com.glsc.ngateway.common.api.flowable.resp.*;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrDeptDto;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrEmpDto;
import com.glsc.ngateway.common.api.ldap.feign.IFeignLdapService;
import com.glsc.ngateway.common.api.ldap.resp.AppEhrResponse;
import com.glsc.ngateway.common.api.platform.dto.user.PlatformUserDto;
import com.glsc.ngateway.common.api.shortmsg.bo.MessageGenericVo;
import com.glsc.ngateway.common.api.shortmsg.feign.IFeignShortmsgService;
import com.glsc.ngateway.common.base.converter.platform.FlowFormEventConverter;
import com.glsc.ngateway.common.base.domain.mysql.gateway.ldap.LdapEhrDept;
import com.glsc.ngateway.common.base.domain.mysql.gateway.other.SystemConfig;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.Appendix;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.User;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowEventUnionImporove;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormEvent;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormEventDetailImprove;
import com.glsc.ngateway.common.base.domain.mysql.gateway.system.SystemMain;
import com.glsc.ngateway.common.base.domain.mysql.gateway.system.VEhrAdminStaff;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.AppendixRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowEventUnionImporveRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormEventRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.system.VEhrAdminStaffRepository;
import com.glsc.ngateway.platform.aspect.UserCache;
import com.glsc.ngateway.platform.service.it.DictionaryService;
import com.glsc.ngateway.platform.service.itflow.config.ProcessEditConfigService;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.AbstractHandlerHelper;
import com.glsc.ngateway.platform.service.system.SystemMainService;
import com.glsc.ngateway.platform.service.system.SystemMemberService;
import com.glsc.ngateway.platform.utils.DateUtils;
import com.glsc.ngateway.platform.utils.JsonTool;
import com.glsc.ngateway.platform.utils.report.ReportFileConfigEnum;
import com.glsc.ngateway.platform.utils.report.ReportFileUtil;
import com.google.common.collect.ImmutableList;
import com.netflix.discovery.shared.Pair;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.YearMonth;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.glsc.ngateway.platform.utils.DateUtils.formatDate;
import static com.glsc.ngateway.platform.utils.DateUtils.getCurrentDate;

/**
 * @author zhouzp
 * @date 2022/12/8
 * 事件管理流程服务类，
 */
@Service
public class EventManageService {

    Logger logger = LoggerFactory.getLogger(EventManageService.class);

    @Resource
    private FlowFormEventRepo flowFormEventRepo;

    @Resource
    private FlowEventUnionImporveRepo flowEventUnionImporveRepo;

    @Resource
    private AppendixRepo appendixRepo;

    @Resource
    @Qualifier("transactionManagerMysql")
    private PlatformTransactionManager transactionManager;

    @Resource
    private UserCache userCache;

    @Resource
    private IFeignFlowableService feignFlowableService;

    @Resource
    private FlowCommonService flowCommonService;

    @Resource
    private EventImproveService eventImproveService;

    @Resource
    private ProcessEditConfigService processEditConfigService;

    @Resource
    private SystemConfigService systemConfigService;

    @Resource
    private UserService userService;

    @Resource
    private IFeignLdapService iFeignLdapService;

    @Resource
    private MailService mailService;

    @Resource
    private SystemMemberService systemMemberService;

    @Resource
    private SystemMainService systemMainService;

    @Autowired
    private DictionaryService dictionaryService;

    @Resource
    private IFeignShortmsgService iFeignShortmsgService;

    @Value("${wechat.url}")
    private String weChatUrl;

    @Resource
    private VEhrAdminStaffRepository vEhrAdminStaffRepository;

    /**
     * 保存事件管理流程表单
     *
     * @param formEvent
     * @return
     */
    public FlowFormEvent saveOrUpdateForm(FlowFormEventDto formEvent) {
        return flowFormEventRepo.save(Objects.requireNonNull(FlowFormEventConverter.dto2Do(formEvent)));
    }

    /**
     * 根据processId获取事件管理流程表单
     *
     * @param processId 流程iD
     * @return
     */
    public FlowFormEventDto findFormByProcessId(String processId) {
        FlowFormEvent flowFormEvent = flowFormEventRepo.findByProcessId(processId);
        if (flowFormEvent != null) {
            //填充系统名称
            if (StrUtil.isNotEmpty(flowFormEvent.getSystemCode())) {
                Map<String, String> operationMap = systemMainService.queryAll().stream().filter(e -> StrUtil.isNotEmpty(e.getSystemClassNo())).collect(Collectors.toMap(SystemMain::getSystemClassNo, SystemMain::getOpName));
                flowFormEvent.setSystemName(operationMap.get(flowFormEvent.getSystemCode()));
            }
            //填充管理员名称
            if (StrUtil.isNotEmpty(flowFormEvent.getSystemAdminAccount())){
                LdapEhrEmpDto empDto = userService.getUserFromEhr(flowFormEvent.getSystemAdminAccount());
                if (empDto != null){
                    flowFormEvent.setSystemAdminName(empDto.getName());
                }
            }
        }
        //填充改善人员列表中文
        if (flowFormEvent != null && CollectionUtil.isNotEmpty(flowFormEvent.getDetailImproves())){
            for (FlowFormEventDetailImprove improve:flowFormEvent.getDetailImproves()) {
                if (StrUtil.isNotEmpty(improve.getImprovePersonList()) && improve.getImprovePersonList().split(",").length > 0){
                    List<String> userAccounts = Arrays.asList(improve.getImprovePersonList().split(","));
                    List<LdapEhrEmpDto> empDtoList = userService.getEmpsByAccounts(userAccounts);
                    improve.setImprovePersonNameList(String.join(",",empDtoList.stream().map(LdapEhrEmpDto::getName).collect(Collectors.toList())));
                }
            }
        }
        //TODO 加载附件信息
        if (flowFormEvent != null && StrUtil.isNotBlank(flowFormEvent.getEventReportDocIdList())) {
            String[] docIds = flowFormEvent.getEventReportDocIdList().split(",");
            List<Appendix> docList = new ArrayList<>();
            if (docIds != null && docIds.length > 0) {
                for (String docId : docIds) {
                    Appendix appendix = appendixRepo.findById(docId);
                    docList.add(appendix);
                }
            }
            flowFormEvent.setEventReportDocList(docList);
        }
        return FlowFormEventConverter.do2Dto(flowFormEvent);
    }


    /**
     * 创建流程
     *
     * @param eventTaskDto 流程创建发起对象
     * @return
     */
    public FlowDoTaskRespDto createFlow(EventTaskDto eventTaskDto, String operatorStart) {
        if (ObjectUtil.isNull(eventTaskDto)
                || ObjectUtil.isNull(eventTaskDto.getFlowableFormData())
                || StrUtil.isEmpty(operatorStart)) {
            throw PlatformException.errorWithOutMail("流程创建必填要素不能为空");
        }

        PlatformUserDto createUser = userCache.get(operatorStart);

        //【流程节点】，发起时动态指定节点处理人，
        Map<String, String> taskAssignee = this.initTaskUserGroup(operatorStart, eventTaskDto.getFlowableFormData().getSystemAdminAccount());
        //【流程节点变量】
        Map<String, String> conditionalVariable = new HashMap<>();

        TransactionStatus status = null;
        FlowDoTaskRespDto createFlowResponse = null;
        FlowFormEventDto flowableForm = eventTaskDto.getFlowableFormData();
        try {
            // 事务定义
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            // 每次都开启一个新事务
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 获取事务状态
            status = transactionManager.getTransaction(def);

            //2.表单内容（发起流程，表单内容为辅助）
            FlowStartupFormDto formDto = new FlowStartupFormDto();
            formDto.setTitle(flowableForm.getProcessTitle());
            formDto.setComment("xx");//发起备注
            formDto.setCreatorId(createUser.getUserid());
            formDto.setCreatorName(createUser.getUsername());


            ParamCreateDto paramCreateDto = new ParamCreateDto();
            paramCreateDto.setSysid(PlatformConstant.SYS_ID_GATEWAY);
            paramCreateDto.setProcessDefinitionKey(PlatformConstant.FLOW_KEY_EVENT_MANAGE);
            paramCreateDto.setUserid(operatorStart);//【重要！】这字段标识发起人！！！
            paramCreateDto.setContent(JSONObject.toJSON(formDto).toString());//纯粹为了flowable创建content需要一个JSON表单数据
            paramCreateDto.setTaskAssignee(taskAssignee);//各节点处理人
            paramCreateDto.setConditionalVariable(conditionalVariable);//控制流程节点变量
            paramCreateDto.setCreateComment(eventTaskDto.getCommentDto().getFullMessage());


            createFlowResponse = new FlowDoTaskRespDto();
            //4.创建flowable流程
            FlowableResponse<ResponseCreateDto> createFlowableFlowResponse = feignFlowableService.create(paramCreateDto);
            if (createFlowableFlowResponse.getStatus() == 0) {
                createFlowResponse.setProcessId(createFlowableFlowResponse.getData().getProcessId());
                logger.info("流程关联，{}", createFlowResponse);
            } else {
                String errMsg = String.format("流程创建失败，{%s}，错误码={%s}-，原因：{%s}",
                        flowableForm.getProcessTitle()
                        , createFlowableFlowResponse.getStatus(), createFlowableFlowResponse.getMsg());
                logger.error(errMsg);
                throw PlatformException.error(errMsg);
            }
//            //抄送并邮件给团队长
//            if (Strings.isBlank(createUser.getUserDepartment())) {
//                logger.info("发起事件：发起人无部门，无需抄送");
//            } else {
//                AppEhrResponse<LdapEhrDeptDto> depResp = iFeignLdapService.getDepByAccount(createUser.getUsername());
//                if (Objects.isNull(depResp) || depResp.getStatus() != 0) {
//                    throw PlatformException.error("未找到部门信息");
//                }
//                LdapEhrDept depInfo = JSONObject.parseObject(JSONObject.toJSONString(depResp.getData()), LdapEhrDept.class);
//                if (!"二级部门".equals(depInfo.getDepgrade()) || Strings.isBlank(depInfo.getLeader())) {
//                    logger.info(!"二级部门".equals(depInfo.getDepgrade()) ?
//                            String.format("发起事件：非二级部门无需转发团队长, %s, %s", depInfo.getDepgrade(), depInfo.getDtitle())
//                            : String.format("发起事件：部门无团队长, 不转发, %s, %s", depInfo.getDepgrade(), depInfo.getDtitle())
//                    );
//                } else {
//                    if (depInfo.getLeader().equals(operatorStart)) {
//                        logger.info(String.format("发起时间：发起人即团队长，无需抄送，%s, %s", operatorStart, depInfo.getDtitle()));
//                    } else {
//                        AppEhrResponse<LdapEhrEmpDto> leaderResp = iFeignLdapService.getLdapEhrEmp(depInfo.getLeader(), null, false);
//                        if (Objects.isNull(leaderResp) || !leaderResp.isSuccess() || Objects.isNull(leaderResp.getData())) {
//                            logger.error("事件抄送异常：未找到leader信息-{}", depInfo.getLeader());
//                        } else {
//                            LdapEhrEmpDto leader = leaderResp.getData();
//                            ParamCopyDto copyParam = new ParamCopyDto();
//                            copyParam.setProcessId(createFlowableFlowResponse.getData().getProcessId());
//                            copyParam.setSysid(PlatformConstant.SYS_ID_GATEWAY);
//                            copyParam.setAddComment(false);
//                            copyParam.setUsernameSource(operatorStart);
//                            copyParam.setUsernameDestination(leader.getBadge());
//                            //抄送流程
//                            feignFlowableService.copyProcess(copyParam);
//                            //邮件通知
//                            FlowFormEventDto event = eventTaskDto.getFlowableFormData();
//                            String title = String.format("【抄送】-【事件流程】-【%s】", event.getProcessTitle());
//                            String content = String.format("事件标题：%s<br/>  发起人：%s<br/>  事件系统：%s<br/>  负责人：%s<br/>  事件分级：%s<br/>  事件分类：%s<br/>  事件概要：%s<br/>  请知悉。可至国联技术服务平台内查阅相关事宜。"
//                                    , event.getEventTitle()
//                                    , event.getFlowCreateOperatorName()
//                                    , Optional.ofNullable(systemMainService.findBySystemClassNo(event.getSystemCode()))
//                                            .orElseThrow(() -> PlatformException.error("未找到系统：" + event.getSystemCode())).getOpName()
//                                    , userCache.get(event.getSystemAdminAccount()).getName()
//                                    , (Objects.isNull(event.getEventGrade()) ? "无" :
//                                            Optional.ofNullable(dictionaryService.findByDictEntryAndDictSubentry("event_manage_grade", event.getEventGrade()))
//                                                    .orElseThrow(() -> PlatformException.error("未找到字典项：event_manage_grade， " + event.getEventGrade())).getDictValue())
//                                    , (Objects.isNull(event.getEventClass()) ? "无" :
//                                            Optional.ofNullable(dictionaryService.findByDictEntryAndDictSubentry("event_manage_class", event.getEventClass()))
//                                                    .orElseThrow(() -> PlatformException.error("未找到字典项：event_manage_class， " + event.getEventClass())).getDictValue())
//                                    , event.getEventSummary()
//                            );
//                            mailService.sendMail(new String[]{leader.getEmail()}, null, title
//                                    , AbstractHandlerHelper.GATEWAY_EVENT_URL + "flowAudit?flowProcessId=" + createFlowableFlowResponse.getData().getProcessId()
//                                    , title, content, null, Constant.MAIL_TYPE_IT_FLOW
//                            );
//                        }
//                    }
//                }
//            }

            //流程表单个性化要素保存（设置关联的流程）
            flowableForm.setProcessId(createFlowResponse.getProcessId());
            //保存流程部门，为系统负责人所在部门
            PlatformUserDto user = userService.getUsrUrls(flowableForm.getSystemAdminAccount());
            flowableForm.setSystemBelongDepartment(user.getDepartment());
            //保存申请人部门信息
            PlatformUserDto userCreater = userService.getUsrUrls(flowableForm.getFlowCreateOperatorAccount());
            flowableForm.setFlowCreatorDepartment(userCreater.getDepartment());
            FlowFormEvent flowableFormData = this.saveOrUpdateForm(flowableForm);

            //TODO 保存附件


            //提交事务
            transactionManager.commit(status);
        } catch (Exception e) {
            logger.error("异常，", e);

            String errMsg = "产品终止流程创建出现异常，回滚当前事务，原因:" + e.getMessage();
            if (status != null) {
                logger.error(errMsg);
                transactionManager.rollback(status);
            }
            throw PlatformException.error(errMsg);
        }

        return createFlowResponse;
    }

    private Map<String, String> initTaskUserGroup(String operatorStart, String systemAdminAccount) {
        //流程节点，发起时动态指定节点处理人，
        Map<String, String> taskAssignee = new HashMap<>();

        String eventManageAccount = systemConfigService.findConfigValueByCode("EVENT_MANAGE_ACCOUNT");
        String eventSysAdminAccount = systemConfigService.findConfigValueByCode("EVENT_SYS_ADMIN_ACCOUNT");

        //TODO 需要查找具体的人员
        taskAssignee.put("reporterGroup", systemAdminAccount);//流程发起人
        taskAssignee.put("eventManageGroup", eventManageAccount);//张文，需要配置角色
        taskAssignee.put("sysadminGroup", eventSysAdminAccount);//需要找每个系统对应的负责人

        return taskAssignee;
    }


    /**
     * 保存节点数据，但是不提交任务
     */
    public FlowDoTaskRespDto saveFormData(EventTaskDto eventTaskDto, String operatorStart) {
        if (ObjectUtil.isNull(eventTaskDto)
                || ObjectUtil.isNull(eventTaskDto.getFlowableFormData())
                || StrUtil.isEmpty(operatorStart)) {
            throw PlatformException.error("流程保存必填要素不能为空");
        }//TODO检查其它必填要素

        FlowDoTaskRespDto respDto = null;
        if (StrUtil.isNotEmpty(eventTaskDto.getTaskId())) {//TODO 正式上线时，需要把taskId必传给打开
            respDto = flowCommonService.validCheckTaskBeforeSaveFormOrAuditTask(eventTaskDto.getTaskId());
        } else {
            respDto = new FlowDoTaskRespDto();
        }
        FlowFormEventDto flowableFormData = eventTaskDto.getFlowableFormData();
        if (StrUtil.isNotEmpty(respDto.getProcessId())) {
            flowableFormData.setProcessId(respDto.getProcessId());
        }
        this.saveOrUpdateForm(eventTaskDto.getFlowableFormData());

        return respDto;
    }


    /**
     * 审核通过
     */
    public FlowDoTaskRespDto taskAuditPass(EventTaskDto taskDto, String operatorAccount) {

        //【1.任务合法性数据】
        FlowDoTaskRespDto respDto = flowCommonService.validCheckTaskBeforeSaveFormOrAuditTask(taskDto.getTaskId());
        //根据查询出的节点类型赋值
        taskDto.setTaskDefinitionKey(respDto.getTaskDefinitionKey());

        //流程注入变量更新
        Map<String, String> taskAssignee = new HashMap<>();
        Map<String, String> conditionalVariable = new HashMap<>();

        //TODO 节点个性化处理
        if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_BEGIN_TASK.equals(taskDto.getTaskDefinitionKey())) {//
            taskAssignee = this.initTaskUserGroup(operatorAccount, taskDto.getFlowableFormData().getSystemAdminAccount());

        } else if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_ANALYSIS.equals(taskDto.getTaskDefinitionKey())) {//
            checkEventLevelFile(taskDto);
        } else if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_LEADER.equals(taskDto.getTaskDefinitionKey())) {//
            checkEventLevelFile(taskDto);
        } else if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_AUDIT.equals(taskDto.getTaskDefinitionKey())) {//
            //要先保存记录，再去关联

        } else if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_TRACE.equals(taskDto.getTaskDefinitionKey())) {//
            //标记关闭
            taskDto.getFlowableFormData().setIsClose(1);
        }
        String groupLeaderAccount = "";
        //审核事务通过
        TransactionStatus status = null;
        try {
            // 事务定义
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            // 每次都开启一个新事务
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 获取事务状态
            status = transactionManager.getTransaction(def);

            //保存表单数据
            FlowDoTaskRespDto saveRespDto = this.saveFormData(taskDto, operatorAccount);
            if (saveRespDto == null) {
                throw PlatformException.error("保存表单数据失败");
            }
            if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_BEGIN_TASK.equals(taskDto.getTaskDefinitionKey())) {//


            } else if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_ANALYSIS.equals(taskDto.getTaskDefinitionKey())) {//
                //给节点处理人赋予处理人，如果当前人员是团队长，则跳过团队长审批节点
                AppEhrResponse<LdapEhrDeptDto> depResp = iFeignLdapService.getDepByAccount(taskDto.getFlowableFormData().getSystemAdminAccount());
                if (Objects.isNull(depResp) || depResp.getStatus() != 0) {
                    throw PlatformException.error("未找到部门信息");
                }
                LdapEhrDept depInfo = JSONObject.parseObject(JSONObject.toJSONString(depResp.getData()), LdapEhrDept.class);
                groupLeaderAccount = depInfo.getLeader();
                if (!"二级部门".equals(depInfo.getDepgrade()) || Strings.isBlank(depInfo.getLeader()) || depInfo.getLeader().equals(taskDto.getFlowableFormData().getSystemAdminAccount())) {
                    //特殊情况，团队长审批节点跳过
                    conditionalVariable.put("hasLeaderTask",DictConstant.WORKFLOW_NODE_SKIP);
                } else {
                    conditionalVariable.put("hasLeaderTask",DictConstant.WORKFLOW_NODE_NO_SKIP);
                    taskAssignee.put("leaderGroup",depInfo.getLeader());
                }
            } else if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_AUDIT.equals(taskDto.getTaskDefinitionKey())) {//
                //关联整改id
                //审核通过后创建改进流程
                if (CollectionUtil.isNotEmpty(taskDto.getFlowableFormData().getDetailImproves())) {
                    for (FlowFormEventDetailImproveDto improveItem : taskDto.getFlowableFormData().getDetailImproves()) {

                        //获取整改负责人姓名
                        String improvePersonList = improveItem.getImprovePersonList();
                        String improvePersonNameList = "";
                        if (StrUtil.isNotEmpty(improvePersonList)) {
                            String[] personAccounts = improvePersonList.split(",");
                            for (String person : personAccounts) {
                                PlatformUserDto user = userCache.get(person);
                                if (user == null) {
                                    user = userService.saveUserByUserName(person);
                                }
                                if (user != null) {
                                    improvePersonNameList = improvePersonNameList + user.getName() + ",";
                                }
                            }
                            if (improvePersonNameList.length() > 1) {
                                improvePersonNameList = improvePersonNameList.substring(0, improvePersonNameList.length() - 1);
                            }
                        }

                        EventImproveTaskDto eventImproveTaskDto = new EventImproveTaskDto();
                        FlowFormEventImproveDto formData = new FlowFormEventImproveDto();
                        BeanUtil.copyProperties(improveItem, formData);
                        formData.setProcessTitle(improveItem.getImproveTitle() + "-事件整改流程-" + improvePersonNameList + "-" + getCurrentDate(formatDate));
                        formData.setFromImproveId(improveItem.getImproveId());
                        formData.setFlowCreateOperatorAccount("系统自动创建");
                        formData.setFlowCreateOperatorName("系统自动创建");
                        formData.setFromEventProcessId(taskDto.getFlowableFormData().getProcessId());
                        formData.setFromEventProcessTitle(taskDto.getFlowableFormData().getProcessTitle());
                        eventImproveTaskDto.setFlowableFormData(formData);
                        FlowDoTaskRespDto respCreate = eventImproveService.createFlow(eventImproveTaskDto, "admin");
                        improveItem.setImproveProcessId(respCreate.getProcessId());
                    }
                    saveRespDto = this.saveFormData(taskDto, operatorAccount);
                    if (saveRespDto == null) {
                        throw PlatformException.error("保存表单数据失败");
                    }
                }

            } else if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_TRACE.equals(taskDto.getTaskDefinitionKey())) {//


            }

            //审核流程通过，组织表单内容、审核注入变量、评论等
            ParamDoTaskDto paramDotaskDto = new ParamDoTaskDto();
            paramDotaskDto.setSysid(PlatformConstant.SYS_ID_GATEWAY);
            paramDotaskDto.setTaskId(taskDto.getTaskId());
            paramDotaskDto.setComment(flowCommonService.initCommentDto(taskDto.getCommentDto()));
            paramDotaskDto.setTitle("");
            paramDotaskDto.setContent(JsonTool.objectToJson(paramDotaskDto));//flowable网关保存每次审批的全量数据
            paramDotaskDto.setTaskAssignee(taskAssignee);
            paramDotaskDto.setConditionalVariable(conditionalVariable);
            paramDotaskDto.setComment(taskDto.getCommentDto());


            //调用网关审核，注意前面表单的保存与这里审批通过，事物可能不一致，暂时不予处理这种不一致的情况
            FlowableResponse<ResponseMsgDto> flowableResponse = flowCommonService.taskAuditPass(paramDotaskDto);
            if (0 == flowableResponse.getStatus()) {
                //提交事务
                transactionManager.commit(status);

                return respDto;
            } else {
                String errMsg = "流程审核失败，错误码" + flowableResponse.getStatus() + "，原因：" + flowableResponse.getMsg() + "，详情：" + flowableResponse.getData();
                logger.error(errMsg);
                throw PlatformException.error(errMsg);
            }
        } catch (Exception e) {
            mailService.sendMailToAdmin("事务事件流程审核异常", e.getMessage());
            if (status != null) {
                logger.error("事务事件流程创建出现异常，回滚当前事务");
                transactionManager.rollback(status);
            } else {
                logger.error("事务事件出现异常，transaction def status is null");
            }
            throw e;
        } finally {
            //发送邮件和微信通知
            if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_ANALYSIS.equals(taskDto.getTaskDefinitionKey())) {
                notify(taskDto.getFlowableFormData(),ImmutableList.of(groupLeaderAccount));
            }
            if (PlatformConstant.FLOW_EVENT_MANAGE_NODE_LEADER.equals(taskDto.getTaskDefinitionKey())) {
                String eventManageAccount = systemConfigService.findConfigValueByCode("EVENT_MANAGE_ACCOUNT");
                notify(taskDto.getFlowableFormData(),ImmutableList.of(eventManageAccount));
            }
        }
    }

    public void notify(@NotNull FlowFormEventDto event, List<String> notifyAccount) {
        String[] mailList = userService.findAllByAccountList(notifyAccount).stream().map(User::getEmail).toArray(String[]::new);;
        SystemConfig agentIdConfig = systemConfigService.findByCode("WECHAT_GATEWAY_APP_AGENTID");
        boolean hasAgentIdConfig = Objects.nonNull(agentIdConfig) && Strings.isNotBlank(agentIdConfig.getConfigValue());
        //邮件通知
        String title = String.format("【事件流程】-【事件审核】-【%s】", event.getProcessTitle());
        String content = String.format("事件标题：%s<br/>  发起人：%s<br/>  事件系统：%s<br/>  负责人：%s<br/>  事件分级：%s<br/>  事件分类：%s<br/>  事件概要：%s<br/>  请知悉。可至国联技术服务平台内查阅相关事宜。"
                , event.getEventTitle()
                , event.getFlowCreateOperatorName()
                , Optional.ofNullable(systemMainService.findBySystemClassNo(event.getSystemCode()))
                        .orElseThrow(() -> PlatformException.error("未找到系统：" + event.getSystemCode())).getOpName()
                , userCache.get(event.getSystemAdminAccount()).getName()
                , (Objects.isNull(event.getEventGrade()) ? "无" :
                        Optional.ofNullable(dictionaryService.findByDictEntryAndDictSubentry("event_manage_grade", event.getEventGrade()))
                                .orElseThrow(() -> PlatformException.error("未找到字典项：event_manage_grade， " + event.getEventGrade())).getDictValue())
                , (Objects.isNull(event.getEventClass()) ? "无" :
                        Optional.ofNullable(dictionaryService.findByDictEntryAndDictSubentry("event_manage_class", event.getEventClass()))
                                .orElseThrow(() -> PlatformException.error("未找到字典项：event_manage_class， " + event.getEventClass())).getDictValue())
                , event.getEventSummary() != null && event.getEventSummary().length() > 500 ? event.getEventSummary().substring(0, 500) + "..." : event.getEventSummary()
        );
        LocalDateTime referenceDateTime = LocalDateTime.of(2024, Month.MAY,10,18,00); // 这里时间为 20240510
        if ((event.getInsertTime() != null && event.getInsertTime().isAfter(referenceDateTime)) || systemConfigService.findByCode("NEW_EVENT_NOTIFY") != null ){
            mailService.sendMail(mailList, null, title
                    , AbstractHandlerHelper.GATEWAY_EVENT_URL + "flowAudit?flowProcessId=" + event.getProcessId()
                    , title, content, null, Constant.MAIL_TYPE_IT_FLOW
            );
            if (hasAgentIdConfig) {
                iFeignShortmsgService.sendAgentMessageGeneric(MessageGenericVo.builder()
                        .oaUserAccounts(notifyAccount)
                        .agentId(agentIdConfig.getConfigValue())
                        .textContent("<br><a href='" + weChatUrl + "'>" + title + "</a>" +
                                "<br>  " + content)
                        .build());
            }
        }
    }

    private void checkEventLevelFile(EventTaskDto taskDto) {
        //1 事件登记为中级，上传文件word必选
        //2 事件登记为高级强制要求pdf和word都要，必选
        List<AppendixDto> docList = taskDto.getFlowableFormData().getEventReportDocList();
        List<String> docPostfix = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(docList)) {
            docPostfix = docList.stream().map(appendix -> {
                int idx = appendix.getAppendixName().lastIndexOf(".");
                return appendix.getAppendixName().substring(idx + 1).toUpperCase();
            }).collect(Collectors.toList());
        }
        if (taskDto.getFlowableFormData().getEventGrade().equals("1")) {
            //中级
            if (CollectionUtil.isEmpty(docList)) {
                throw PlatformException.errorWithOutMail("事件等级为中级，上传文件word必选");
            }
            if (!(docPostfix.contains("DOC") || docPostfix.contains("DOCX")) || !(docPostfix.contains("PDF"))) {
                throw PlatformException.errorWithOutMail("事件等级为中级，word和pdf报告均必填");
            }
        } else if (taskDto.getFlowableFormData().getEventGrade().equals("2")) {
            //高级
            if (CollectionUtil.isEmpty(docList)) {
                throw PlatformException.errorWithOutMail("事件等级为高级，word和pdf报告均必填");
            }
            if (!(docPostfix.contains("DOC") || docPostfix.contains("DOCX")) || !(docPostfix.contains("PDF"))) {
                throw PlatformException.errorWithOutMail("事件等级为高级，word和pdf报告均必填！");
            }
        }
    }


    /**
     * 审核驳回
     */
    public FlowDoTaskRespDto taskAuditReject(EventTaskDto taskDto, String operatorStart) {

        //【1.任务合法性数据】
        FlowDoTaskRespDto respDto = flowCommonService.validCheckTaskBeforeSaveFormOrAuditTask(taskDto.getTaskId());


        //【2.公共处理】检查文件必传性，zzp  TODO

        //【3.获取任务审核前的流程信息】
        ResponseSituationDto beforeAuditFlowInfo = flowCommonService.getProcessInfo(respDto.getProcessId());
        //END OF【公共处理】查询任务基础信息

        //各节点，驳回时，业务逻辑特殊处理

        ParamRollbackDto flowableTaskDto = new ParamRollbackDto();
        flowableTaskDto.setSysid(PlatformConstant.SYS_ID_GATEWAY);
        flowableTaskDto.setTaskId(taskDto.getTaskId());
        flowableTaskDto.setComment(flowCommonService.initCommentDto(taskDto.getCommentDto()).getFullMessage());
        flowableTaskDto.setTitle("XXXXX");
        flowableTaskDto.setContent(JsonTool.objectToJson(flowableTaskDto));
        //驳回时，要求提供title、comment
        flowableTaskDto.setComment(taskDto.getCommentDto().getFullMessage());

        FlowableResponse<FlowDoTaskRespDto> flowableResponse = flowCommonService.taskAuditReject(flowableTaskDto);
        if (0 == flowableResponse.getStatus()) {
            //流程回退成功,后续处理 TODO

            return flowableResponse.getData();
        } else {
            throw PlatformException.error("流程退回失败");
        }
    }

    /**
     * 根据流程实例ID或者任务ID检索流程
     *
     * @param taskDto processId 流程ID
     * @param taskDto taskId 任务ID
     */
    public EventTaskDto getWorkFlowFormByTaskId(EventTaskDto taskDto) {
        if (taskDto == null || StrUtil.isEmpty(taskDto.getTaskId()) && StrUtil.isEmpty(taskDto.getProcessId())) {
            throw PlatformException.error("查询产品终止流程时，需要提供流程实例Id或者任务Id和流程节点标识");
        }

        EventTaskDto respDto = new EventTaskDto();


        ResponseSituationDto currentTaskInfo = null;
        if (StrUtil.isEmpty(taskDto.getTaskId())) {//流程结束或者抄送查看流程时，仅根据processId检索要素信息
            respDto.setProcessId(taskDto.getProcessId());
            respDto.setHandleProcessMode(PlatformConstant.FLOWABLE_HANDLE_MODE_VIEW);
            respDto.setCurrentTaskInfo(new ResponseSituationDto());//减轻前段判空处理
        } else {
            taskDto.setTaskId(StrUtil.trim(taskDto.getTaskId()));
            respDto.setHandleProcessMode(PlatformConstant.FLOWABLE_HANDLE_MODE_EDIT);
            FlowableResponse<ResponseSituationDto> flowableTaskInfoResponse = flowCommonService.getTaskInfo(taskDto.getTaskId()
                    , PlatformConstant.SYS_ID_GATEWAY);
            if (flowableTaskInfoResponse.getStatus() != 0) {
                throw PlatformException.error("流程引擎未查询到任务信息" + taskDto.getTaskId());
            } else {
                taskDto.setProcessId(flowableTaskInfoResponse.getData().getProcessId());//后续保存策略会用到processId
                currentTaskInfo = flowableTaskInfoResponse.getData();
                respDto.setCurrentTaskInfo(currentTaskInfo);//task 任务详情
                respDto.setProcessId(currentTaskInfo.getProcessId());
                respDto.setTaskId(currentTaskInfo.getCurrentTaskId());//具体任务方式查看，需要taskId/taskDefinitionKey
                respDto.setTaskDefinitionKey(currentTaskInfo.getCurrentTaskDefinitionKey());
                respDto.setProcessDefineKey(currentTaskInfo.getProcessDefineKey());

                //加载任务节点信息
                ProcessEditConfigDto editConfigDto = processEditConfigService.getProcessEditConfigDto(respDto.getProcessDefineKey(), respDto.getTaskDefinitionKey());
                respDto.setProcessEditConfigDto(editConfigDto);
            }
        }

        //查询表单数据
        FlowFormEventDto flowFormEvent = this.findFormByProcessId(respDto.getProcessId());
        respDto.setFlowableFormData(flowFormEvent);

        return respDto;
    }

    public Map<String, List<EventStatisticDto>> eventStatistics(EventStatisticParamDto param, String account) {
        Map<String, List<EventStatisticDto>> resultMap = new HashMap<>();
        LocalDateTime start = DateUtils.formatDateToLocalDateTime(DateUtils.formatDateString_(param.getStartTime()));
        LocalDateTime end = DateUtils.formatDateToLocalDateTime(DateUtils.formatDateString_(param.getEndTime()));
        if (end != null) {
            end = end.plusDays(1);
        }

////        List<String> departmentList = new ArrayList<>();
//        List<String> systemBelongDepartmentList = new ArrayList<>();
//        //总裁室看全部，一级部门领导看所有二级部门和下属，二级部门看当前部门
//
//        //获取部门信息，判断是否为一二级部门领导
//        AppEhrResponse depts = feignEhrService.getAllDept();
//        List<TAmEhrDeptinfoEntity> deptinfoEntityList = userService.convertEhrDeptList(depts);
//        Map<String,TAmEhrDeptinfoEntity> deptMap = deptinfoEntityList.stream().collect(Collectors.toMap(TAmEhrDeptinfoEntity::getLeader, Function.identity(), (K1, K2) -> K2));
//        Map<Integer,TAmEhrDeptinfoEntity> deptIdMap = deptinfoEntityList.stream().collect(Collectors.toMap(TAmEhrDeptinfoEntity::getDepid, Function.identity(), (K1, K2) -> K2));
//        //获取可以查看的部门
//        systemBelongDepartmentList = getBelongDepartmentList(account, null,deptinfoEntityList,deptMap,deptIdMap);
//
//        //管理员看全部
//        if(userService.userRoleContain(Constant.EVENT_ADMIN,account)){
//            systemBelongDepartmentList = null;
//            //管理员可以看全部，处理一下参数
//            if (StrUtil.isEmpty(param.getFlowCreateOperatorAccount())){
//                param.setFlowCreateOperatorAccount(null);
//            }
//        } else if(CollectionUtil.isEmpty(systemBelongDepartmentList)){
//            //总裁室看全部
//            if (StrUtil.isEmpty(param.getFlowCreateOperatorAccount())){
//                param.setFlowCreateOperatorAccount(null);
//            }
//        } else {
//            if (!deptMap.keySet().contains(account)){
//                //普通员工只能看自己
//                param.setFlowCreateOperatorAccount(account);
//            }
//        }
//        与查询统一权限控制
        //管理员	全部
        //团队长	 系统归属部门=团队 or 提交人 in （团队成员）or 整改负责人/负责人 in （团队成员）or 一般人员权限
        //系统管理员	系统= “”  or 一般人员权限
        //一般人员	提交人=“” or 负责人=“” or 整改负责人=""
//获取部门信息，判断是否为一二级部门领导
        AppEhrResponse<List<LdapEhrDeptDto>> depts = iFeignLdapService.getAllDept();
        List<LdapEhrDeptDto> deptinfoEntityList = Objects.nonNull(depts) && CollectionUtil.isNotEmpty(depts.getData()) ? depts.getData() : Collections.EMPTY_LIST;

        FlowParamAuthDto authCondition = new FlowParamAuthDto();
//        //权限控制
//        if (userService.userRoleContain(Constant.EVENT_ADMIN, account)) {
//            //管理员不做条件控制
//        } else {
//
//            Map<String, LdapEhrDeptDto> deptMap = deptinfoEntityList.stream().collect(Collectors.toMap(LdapEhrDeptDto::getLeader, Function.identity(), (K1, K2) -> K2));
////            Map<Integer,TAmEhrDeptinfoEntity> deptIdMap = deptinfoEntityList.stream().collect(Collectors.toMap(TAmEhrDeptinfoEntity::getDepid, Function.identity(), (K1, K2) -> K2));
////            User u = userService.getUserFromEhr(account);
//            if (deptMap.containsKey(account)) {
//                //一级部门领导
//                LdapEhrDeptDto dept = deptMap.get(account);
//                if (dept.getDepgrade().equals(DictConstant.LEVEL_ONE_DEPARTMENT)) {
//                    List<String> secondDepts = deptinfoEntityList.stream().filter(d -> Objects.equals(d.getAdminid(), dept.getDepid())).map(LdapEhrDeptDto::getDtitle).collect(Collectors.toList());
//                    secondDepts.add(dept.getDtitle());
//                    authCondition.setBelongDepartment(secondDepts);
//                } else {
//                    //二级部门领导
//                    authCondition.setBelongDepartment(ImmutableList.of(dept.getDtitle()));
//                }
//                //获取部门下所有人员账号
//                List<String> userAccount = userService.getUserByDepts(authCondition.getBelongDepartment()).stream().map(LdapEhrEmpDto::getBadge).collect(Collectors.toList());
//                authCondition.setCreatorEmps(userAccount);
//                authCondition.setSystemAdminEmps(userAccount);
//                authCondition.setImproveAdminEmps(userAccount); //整改负责人（实际没用到，转换成下方的工作流id了方便查询）
//            }
//            //判断是否为系统管理员
//            List<String> systemCodes = systemMemberService.querySystemCodeByMemberAccount(account);
//            if (CollectionUtil.isNotEmpty(systemCodes)) {
//                authCondition.setAdminSystem(systemCodes);
//            }
//            //一般人员权限
//            {
//                List<String> emps = authCondition.getCreatorEmps();
//                emps.add(account);
//                authCondition.setCreatorEmps(emps);
//                authCondition.setSystemAdminEmps(emps);
//                authCondition.setImproveAdminEmps(emps);//整改负责人（实际没用到，转换成下方的工作流id了方便查询）
//            }
//            //遍历改善人员获取到的processid
//            List<FlowFormEventDetailImprove> improveDetails = eventImproveService.queryByImprovePersonList(authCondition.getImproveAdminEmps())
//                    .stream().filter(f -> f.getProcessId() != null).collect(Collectors.toList());
//            List<String> processIds = improveDetails.stream().map(e -> e.getProcessId()).collect(Collectors.toList());
//            authCondition.setProcessIds(processIds);
//        }
//
//        List<FlowFormEvent> flowFormEventList = null;
//        if (userService.userRoleContain(Constant.EVENT_ADMIN, account)) {
//            flowFormEventList = flowFormEventRepo.eventStatistics(start, end, param.getFlowCreateOperatorAccount(), param.getEventCause(),param);
//        } else if (CollectionUtil.isNotEmpty(authCondition.getBelongDepartment()) && CollectionUtil.isNotEmpty(authCondition.getAdminSystem())) {
//            //既是团队长，又是系统管理员
//            flowFormEventList = flowFormEventRepo.eventStatisticsWith(start, end, param.getFlowCreateOperatorAccount(), authCondition, param.getEventCause(),param);
//        } else if (CollectionUtil.isNotEmpty(authCondition.getBelongDepartment())) {
//            //是团队长
//            flowFormEventList = flowFormEventRepo.eventStatisticsBelongDepartment(start, end, param.getFlowCreateOperatorAccount(), authCondition, param.getEventCause(),param);
//        } else if (CollectionUtil.isNotEmpty(authCondition.getAdminSystem())) {
//            //是系统管理员
//            flowFormEventList = flowFormEventRepo.eventStatisticsAdminSystem(start, end, param.getFlowCreateOperatorAccount(), authCondition, param.getEventCause(),param);
//        } else {
//            //一般人员
//            flowFormEventList = flowFormEventRepo.eventStatisticsCommon(start, end, param.getFlowCreateOperatorAccount(), authCondition, param.getEventCause(),param);
//        }

        //查询管理有多少人员，以查出人员在改善流程里的事件
        List<VEhrAdminStaff> staffs = vEhrAdminStaffRepository.findAllByReportTo(account);
        List<FlowFormEventDetailImprove> improveDetails = eventImproveService.queryByImprovePersonList(staffs.stream().map(VEhrAdminStaff::getAccount).collect(Collectors.toList()))
                .stream().filter(f -> StrUtil.isNotEmpty(f.getProcessId())).collect(Collectors.toList());
        List<String> processIds = improveDetails.stream().map(e -> e.getProcessId()).collect(Collectors.toList());
        authCondition.setProcessIds(processIds);
        List<FlowFormEvent> flowFormEventList = null;
        if (!userService.userRoleContain(Constant.EVENT_ADMIN, account)) {
            authCondition.setAdmin("0");
        }
        flowFormEventList = flowFormEventRepo.eventStatisticsView(start, end, param.getFlowCreateOperatorAccount(), authCondition, param.getEventCause(),param,staffs);


        Map<String, String> operationMap = systemMainService.queryAll().stream().filter(e -> StrUtil.isNotEmpty(e.getSystemClassNo())).collect(Collectors.toMap(SystemMain::getSystemClassNo, SystemMain::getOpName));


        //找出一共多少个系统,按照系统分组
        Map<String, List<FlowFormEvent>> systemCodeList = flowFormEventList.stream().filter(event -> event.getSystemCode() != null).collect(Collectors.groupingBy(event -> event.getSystemCode()));

        //找出一共多少个系统,按照人员分组
        Map<String, List<FlowFormEvent>> operaList = flowFormEventList.stream().filter(event -> event.getFlowCreateOperatorAccount() != null).collect(Collectors.groupingBy(event -> event.getFlowCreateOperatorAccount()));

        //按部门统计构造结果
        List<EventStatisticDto> eventListDept = makeResultDept(systemCodeList, operationMap, deptinfoEntityList);
        //按人员统计构造结果
        List<EventStatisticDto> eventListOpera = makeResultOpera(operaList, null);

        resultMap.put("dept", eventListDept);
//        resultMap.put("opera", eventListOpera);
        return resultMap;
    }

    private List<EventStatisticDto> makeResultOpera(Map<String, List<FlowFormEvent>> map, Map<String, String> operationMap) {
        List<EventStatisticDto> eventList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(map)) {
            for (String code : map.keySet()) {
                List<FlowFormEvent> events = map.get(code);
                FlowFormEvent event = events.get(0);
                //返回结果
                EventStatisticDto bean = new EventStatisticDto();
                List<LdapEhrEmpDto> users = userService.getEmpsByAccounts(ImmutableList.of(event.getFlowCreateOperatorAccount()));
                if (CollectionUtil.isNotEmpty(users)) {
                    bean.setDeptId(String.valueOf(users.get(0).getDepid()));
                    bean.setDeptName(users.get(0).getTitle());
                } else {
                    continue;
                }
//                bean.setSystemName(operationMap.get(event.getSystemCode()));
//                bean.setSystemCode(event.getSystemCode());
                bean.setEventSum(events.size());
                bean.setEventClose((int) events.stream().filter(event1 -> event1.getIsClose() == 1).count());
                bean.setEventUnClose((int) events.stream().filter(event1 -> event1.getIsClose() == 0).count());
                bean.setEventHigh((int) events.stream().filter(event1 -> "2".equals(event1.getEventGrade())).count());
                bean.setEventMiddle((int) events.stream().filter(event1 -> "1".equals(event1.getEventGrade())).count());
                bean.setEventLow((int) events.stream().filter(event1 -> "0".equals(event1.getEventGrade())).count());
                bean.setFlowCreateOperatorAccount(users.get(0).getBadge());
                bean.setFlowCreateOperatorName(users.get(0).getName());
                eventList.add(bean);
            }
        }
        eventList.stream().sorted((e1, e2) -> {
            return e1.getFlowCreateOperatorAccount().compareTo(e2.getFlowCreateOperatorAccount());
        });
        return eventList;
    }

    private List<EventStatisticDto> makeResultDept(Map<String, List<FlowFormEvent>> systemCodeList, Map<String, String> operationMap, List<LdapEhrDeptDto> deptinfoEntityList) {
        List<EventStatisticDto> eventList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(systemCodeList)) {
            Map<String, Integer> deptMap = deptinfoEntityList.stream().collect(Collectors.toMap(LdapEhrDeptDto::getDtitle, LdapEhrDeptDto::getDepid, (K1, K2) -> K2));
            for (String code : systemCodeList.keySet()) {
                List<FlowFormEvent> events = systemCodeList.get(code);
                //按照系统所属部门分组
                Map<String, List<FlowFormEvent>> departmentMap = events.stream().filter(event -> event.getSystemBelongDepartment() != null).collect(Collectors.groupingBy(event -> event.getSystemBelongDepartment()));
                for (String department : departmentMap.keySet()) {
                    List<FlowFormEvent> eventDepartment = departmentMap.get(department);
                    FlowFormEvent event = eventDepartment.get(0);
                    //返回结果
                    EventStatisticDto bean = new EventStatisticDto();
//                    List<LdapEhrEmp> users = userService.getEmpsByAccounts(ImmutableList.of(event.getSystemAdminAccount()));
//                    if (CollectionUtil.isNotEmpty(users)) {
//                        bean.setDeptId(String.valueOf(users.get(0).getDepid()));
//                        bean.setDeptName(users.get(0).getTitle());
//                    }
                    bean.setDeptId(deptMap.get(event.getSystemBelongDepartment()) != null ? deptMap.get(event.getSystemBelongDepartment()).toString() : "");
                    bean.setDeptName(event.getSystemBelongDepartment());
                    bean.setSystemName(operationMap.get(event.getSystemCode()));
                    bean.setSystemCode(event.getSystemCode());
                    bean.setEventSum(eventDepartment.size());
                    bean.setEventClose((int) eventDepartment.stream().filter(event1 -> event1.getIsClose() == 1).count());
                    bean.setEventUnClose((int) eventDepartment.stream().filter(event1 -> event1.getIsClose() == 0).count());
                    bean.setEventHigh((int) eventDepartment.stream().filter(event1 -> "2".equals(event1.getEventGrade())).count());
                    bean.setEventMiddle((int) eventDepartment.stream().filter(event1 -> "1".equals(event1.getEventGrade())).count());
                    bean.setEventLow((int) eventDepartment.stream().filter(event1 -> "0".equals(event1.getEventGrade())).count());
                    eventList.add(bean);
                }
            }
        }
        eventList.stream().sorted((e1, e2) -> {
            if (e2.getDeptId() == e1.getDeptId()) {
                return e1.getSystemCode().compareTo(e2.getSystemCode());
            }
            return Integer.compare(Integer.valueOf(e1.getDeptId()), Integer.valueOf(e2.getDeptId()));
        });
        return eventList;
    }

    public Page<ResponseSituationEventDto> getProcessSituationPage(Integer pageNo, Integer pageSize, FlowParamSearchDto paramSearchDto, String account) {
        LocalDateTime start = DateUtils.formatDateToLocalDateTime(DateUtils.formatDateString_(paramSearchDto.getBeginDate()));
        LocalDateTime end = DateUtils.formatDateToLocalDateTime(DateUtils.formatDateString_(paramSearchDto.getEndDate()));
        if (end != null) {
            end = end.plusDays(1);
        }

        paramSearchDto.setBeginDateLocalDate(start);
        paramSearchDto.setEndDateLocalDate(end);

        if (StrUtil.isNotEmpty(paramSearchDto.getSystemCode())) {
            paramSearchDto.setSystemCodes(Arrays.asList(paramSearchDto.getSystemCode().split(",")));
            paramSearchDto.setSystemCode(null);
        }

        AppEhrResponse<List<LdapEhrDeptDto>> depts = iFeignLdapService.getAllDept();
        List<LdapEhrDeptDto> deptinfoEntityList = Objects.nonNull(depts) && CollectionUtil.isNotEmpty(depts.getData()) ? depts.getData() : Collections.EMPTY_LIST;

        if (paramSearchDto.getDeptId() != null) {
            Map<Integer, LdapEhrDeptDto> deptMapDeptId = deptinfoEntityList.stream().collect(Collectors.toMap(LdapEhrDeptDto::getDepid, Function.identity(), (K1, K2) -> K2));
            //如果是一级部门，需要获取其所有二级部门
            LdapEhrDeptDto dept = deptMapDeptId.get(paramSearchDto.getDeptId());
            if (dept.getDepgrade().equals(DictConstant.LEVEL_ONE_DEPARTMENT)) {
                List<String> secondDepts = deptinfoEntityList.stream().filter(d -> d.getAdminid() != null && d.getAdminid().equals(dept.getDepid())).map(LdapEhrDeptDto::getDtitle).collect(Collectors.toList());
                secondDepts.add(dept.getDtitle());
                paramSearchDto.setDeptNames(secondDepts);
            } else {
                //二级部门
                paramSearchDto.setDeptNames(ImmutableList.of(dept.getDtitle()));
            }
        }


        pageNo = PageUtil.initPageNo(pageNo);
        pageSize = PageUtil.initPageSize(pageSize);
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize);
//        //管理员	全部
//        //团队长	 系统归属部门=团队 or 提交人 in （团队成员）or 整改负责人/负责人 in （团队成员）or 一般人员权限
//        //系统管理员	系统= “”  or 一般人员权限
//        //一般人员	提交人=“” or 负责人=“” or 整改负责人=""
//
//        FlowParamAuthDto authCondition = new FlowParamAuthDto();
//        //权限控制
//        if (userService.userRoleContain(Constant.EVENT_ADMIN, account)) {
//            //管理员不做条件控制
//        } else {
//            //获取部门信息，判断是否为一二级部门领导
//
//            Map<String, LdapEhrDeptDto> deptMap = deptinfoEntityList.stream().collect(Collectors.toMap(LdapEhrDeptDto::getLeader, Function.identity(), (K1, K2) -> K2));
////            Map<Integer,TAmEhrDeptinfoEntity> deptIdMap = deptinfoEntityList.stream().collect(Collectors.toMap(TAmEhrDeptinfoEntity::getDepid, Function.identity(), (K1, K2) -> K2));
////            User u = userService.getUserFromEhr(account);
//            if (deptMap.keySet().contains(account)) {
//                //一级部门领导
//                LdapEhrDeptDto dept = deptMap.get(account);
//                if (dept.getDepgrade().equals(DictConstant.LEVEL_ONE_DEPARTMENT)) {
//                    List<String> secondDepts = deptinfoEntityList.stream().filter(d -> Objects.equals(d.getAdminid(), dept.getDepid())).map(LdapEhrDeptDto::getDtitle).collect(Collectors.toList());
//                    secondDepts.add(dept.getDtitle());
//                    authCondition.setBelongDepartment(secondDepts);
//                } else {
//                    //二级部门领导
//                    authCondition.setBelongDepartment(ImmutableList.of(dept.getDtitle()));
//                }
//                //获取部门下所有人员账号
//                List<String> userAccount = userService.getUserByDepts(authCondition.getBelongDepartment()).stream().map(LdapEhrEmpDto::getBadge).collect(Collectors.toList());
//                authCondition.setCreatorEmps(userAccount);
//                authCondition.setSystemAdminEmps(userAccount);
//                authCondition.setImproveAdminEmps(userAccount); //整改负责人（实际没用到，转换成下方的工作流id了方便查询）
//            }
//            //判断是否为系统管理员
//            List<String> systemCodes = systemMemberService.querySystemCodeByMemberAccount(account);
//            if (CollectionUtil.isNotEmpty(systemCodes)) {
//                authCondition.setAdminSystem(systemCodes);
//            }
//            //一般人员权限
//            {
//                List<String> emps = authCondition.getCreatorEmps();
//                emps.add(account);
//                authCondition.setCreatorEmps(emps);
//                authCondition.setSystemAdminEmps(emps);
//                authCondition.setImproveAdminEmps(emps);//整改负责人（实际没用到，转换成下方的工作流id了方便查询）
//            }
//            //遍历改善人员获取到的processid
//            List<FlowFormEventDetailImprove> improveDetails = eventImproveService.queryByImprovePersonList(authCondition.getImproveAdminEmps())
//                    .stream().filter(f -> f.getProcessId() != null).collect(Collectors.toList());
//            List<String> processIds = improveDetails.stream().map(FlowFormEventDetailImprove::getProcessId).collect(Collectors.toList());
//            authCondition.setProcessIds(processIds);
//        }
//
//        Page<FlowEventUnionImporove> result = null;
//        if (userService.userRoleContain(Constant.EVENT_ADMIN, account)) {
//            result = flowEventUnionImporveRepo.searchByParam(pageable, paramSearchDto);
//        } else if (CollectionUtil.isNotEmpty(authCondition.getBelongDepartment()) && CollectionUtil.isNotEmpty(authCondition.getAdminSystem())) {
//            //既是团队长，又是系统管理员
//            result = flowEventUnionImporveRepo.searchByParamWith(pageable, paramSearchDto, authCondition);
//        } else if (CollectionUtil.isNotEmpty(authCondition.getBelongDepartment())) {
//            //是团队长
//            result = flowEventUnionImporveRepo.searchByParamBelongDepartment(pageable, paramSearchDto, authCondition);
//        } else if (CollectionUtil.isNotEmpty(authCondition.getAdminSystem())) {
//            //是系统管理员
//            result = flowEventUnionImporveRepo.searchByParamAdminSystem(pageable, paramSearchDto, authCondition);
//        } else {
//            //一般人员
//            result = flowEventUnionImporveRepo.searchByParamCommon(pageable, paramSearchDto, authCondition);
//        }

        FlowParamAuthDto authCondition = new FlowParamAuthDto();
        //查询管理有多少人员，以查出人员在改善流程里的事件
        List<VEhrAdminStaff> staffs = vEhrAdminStaffRepository.findAllByReportTo(account);
        List<FlowFormEventDetailImprove> improveDetails = eventImproveService.queryByImprovePersonList(staffs.stream().map(VEhrAdminStaff::getAccount).collect(Collectors.toList()))
                .stream().filter(f -> StrUtil.isNotEmpty(f.getProcessId())).collect(Collectors.toList());
        List<String> processIds = improveDetails.stream().map(e -> e.getProcessId()).collect(Collectors.toList());
        authCondition.setProcessIds(processIds);
        Page<FlowEventUnionImporove> result = null;
        if (!userService.userRoleContain(Constant.EVENT_ADMIN, account)) {
            authCondition.setAdmin("0");
        }
        result = flowEventUnionImporveRepo.searchByParamView(pageable, paramSearchDto, authCondition,staffs);

//        result = flowEventUnionImporveRepo.searchByParam(pageable,paramSearchDto);
        List<FlowEventUnionImporove> content = result.getContent();
        List<ResponseSituationEventDto> process = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(content)) {
            for (FlowEventUnionImporove flow : content) {
                FlowableResponse<ResponseSituationDto> processInfo = feignFlowableService.getProcessInfo(flow.getProcessId());
                ResponseSituationEventDto eventDto = new ResponseSituationEventDto();
                BeanUtil.copyProperties(processInfo.getData(), eventDto);
                eventDto.setEventGrade(flow.getEventGrade());
                eventDto.setImproveCount(flow.getImproveCount());
                eventDto.setImproveCountAll(flow.getImproveCountAll());
                eventDto.setSystemCode(flow.getSystemCode());
                eventDto.setEventCause(flow.getEventCause());
                eventDto.setEventClass(flow.getEventClass());
                eventDto.setEventHappenTime(flow.getEventHappenTime());
                eventDto.setFlowCreateOperatorName(flow.getFlowCreateOperatorName());
                eventDto.setFlowCreateOperatorAccount(flow.getFlowCreateOperatorAccount());
                eventDto.setProcessCreateTime(flow.getProcessCreateTime());
                process.add(eventDto);
            }
        }

        Page<ResponseSituationEventDto> resultPage = new PageImpl(process, pageable, result.getTotalElements());
        return resultPage;
    }

    public byte[] export(FlowParamSearchDto paramSearchDto, String operatorStart) throws IOException {
        paramSearchDto.setSystemCode(Strings.isNotBlank(paramSearchDto.getSystemCode()) ? paramSearchDto.getSystemCode() : null);
        Page<ResponseSituationEventDto> page = this.getProcessSituationPage(paramSearchDto.getPageNo(), Integer.MAX_VALUE, paramSearchDto, operatorStart);
        if (CollectionUtils.isEmpty(page.getContent())) {
            throw PlatformException.error("未找到数据", false, false);
        }
        List<EventExportDto> datas = page.getContent().stream()
                .map(s -> {
                    EventExportDto dto = new EventExportDto();
                    dto.setEventTitle(s.getProcessTitle());
                    if (Strings.isNotBlank(s.getEventGrade())) {
                        Optional.ofNullable(dictionaryService.findByDictEntryAndDictSubentry("event_manage_grade", s.getEventGrade()))
                                .ifPresent(dict -> dto.setEventGrade(dict.getDictValue()));
                    }
                    //多条则合并为一个字符串，换行
                    if (Objects.nonNull(s.getImproveCountAll()) && Integer.parseInt(s.getImproveCountAll()) > 0) {
                        dto.setDetailImproves(
                                eventImproveService.findAllByFromEventProcessId(s.getProcessId()).stream()
                                        .map(improve -> improve.getProcessTitle() + (improve.getIsClose() == 1 ? "（已完成）" : "（未完成）"))
                                        .collect(Collectors.joining("\r\n"))
                        );
                    }
                    if (Strings.isNotBlank(s.getSystemCode())) {
                        Optional.ofNullable(systemMainService.findBySystemClassNo(s.getSystemCode()))
                                .ifPresent(sys -> dto.setSystemName(sys.getOpName()));
                    }
                    Optional.ofNullable(dictionaryService.findByDictEntryAndDictSubentry("event_cause", Objects.nonNull(s.getEventCause()) ? String.valueOf(s.getEventCause()) : "0"))
                            .ifPresent(dict -> dto.setEventCause(dict.getDictValue()));
                    if (Strings.isNotBlank(s.getEventClass())) {
                        Optional.ofNullable(dictionaryService.findByDictEntryAndDictSubentry("event_manage_class", s.getEventClass()))
                                .ifPresent(dict -> dto.setEventClass(dict.getDictValue()));
                    }
                    dto.setEventHappenTime(s.getEventHappenTime());
                    dto.setFlowCreateOperatorName(s.getFlowCreateOperatorName());
                    dto.setProcessCreateTime(s.getProcessCreateTime());
                    return dto;
                })
                .collect(Collectors.toList());
        return ReportFileUtil.export(datas, ReportFileConfigEnum.EVENT_FLOW);
    }
}
